import 'dart:ui' as ui;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutterdemo/0demo/ui/gesture/photo_view/constants.dart';
import 'package:flutterdemo/0demo/ui/gesture/photo_view/gesture_listener.dart';

import 'load_asset.dart';
import 'photo_painter.dart';

class MyPhotoView extends StatefulWidget {
  const MyPhotoView({Key key}) : super(key: key);

  @override
  _MyPhotoViewState createState() => _MyPhotoViewState();
}

class _MyPhotoViewState extends State<MyPhotoView>
    with SingleTickerProviderStateMixin {
  ui.Image _image;

  double _newImageHeight = 0;
  double _newImageWidth = 0;
  double _marginLeft = 0;
  double _marginTop = 0;
  double _scale = 1;

  AnimationController _animationController;
  Animation _curve;
  Animation _scaleAnim;

  PhotoScale _currentScale = PhotoScale.normalScale;

  @override
  void initState() {
    loadAssetImage("assets/bg/bg5.jpg").then((i) {
      // loadAssetImage("assets/bg/bg6.png").then((i) {
      setState(() {
        _image = i;
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
          _resetPhotoPosition();
        });
      });
    });

    // 创建动画
    _animationController =
        AnimationController(duration: Duration(seconds: 1), vsync: this);
    // 设置Curve(插值)
    _curve =
        CurvedAnimation(parent: _animationController, curve: Curves.easeInOut);
    // 设置scale
    _scaleAnim = Tween(begin: 1.0, end: 2.0).animate(_curve)
      ..addListener(() {
        _scale = _scaleAnim.value;
        _resetPhotoPosition();
      })
      ..addStatusListener((status) {});
    super.initState();
  }

  void _resetPhotoPosition() {
    if (_image == null) return;
    final size = MediaQuery.of(context).size;
    // fit width scale bigger or smaller.
    // double newImageHeight = _image.height * (size.width / _image.width);
    // double newImageWidth = size.width;

    // fit width if bigger than screen width.
    _newImageHeight = _image.width < size.width
        ? _image.height.toDouble()
        : _image.height * (size.width / _image.width);
    _newImageWidth =
        _image.width < size.width ? _image.width.toDouble() : size.width;

    // process scale
    _newImageHeight *= _scale;
    _newImageWidth *= _scale;
    print(size);
    _marginTop = _newImageHeight <= size.height
        ? (size.height - _newImageHeight) / 2
        : -((_newImageHeight - size.height) / 2);
    _marginLeft = _newImageWidth <= size.width
        ? (size.width - _newImageWidth) / 2
        : -((_newImageWidth - size.width) / 2);

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    return Container(
      color: Colors.black,
      child: GestureListener(
        onDoubleTap: _onDoubleTap,
        onHorizontalDragStart: _onHorizontalDragStart,
        onHorizontalDragUpdate: (details) {
          _onHorizontalDragUpdate(details, context);
        },
        onHorizontalDragEnd: _onHorizontalDragEnd,
        child: CustomPaint(
          size: Size(size.width, size.height),
          painter: PhotoPainter(
              _image, _marginLeft, _marginTop, _newImageWidth, _newImageHeight),
        ),
      ),
    );
  }

  _onDoubleTap(TapDownDetails details) {
    print(details.globalPosition);
    // full screen canvas, globalPosition == localPosition.
    double dx = details.globalPosition.dx;
    double dy = details.localPosition.dy;
    // invalid click bound.
    if (dx < _marginLeft ||
        dy < _marginTop ||
        dx > _marginLeft + _newImageWidth ||
        dy > _marginTop + _newImageHeight) {
      return;
    }
    _scaleByDoubleTap(details);
  }

  void _scaleByDoubleTap(TapDownDetails details) {
    // process animate
    if (_animationController.isAnimating) {
      // 动画正在执行
      return;
    }
    _currentScale == PhotoScale.normalScale
        ? _animationController.forward()
        : _animationController.reverse();

    if (_currentScale != PhotoScale.doubleScale) {
      _currentScale = PhotoScale.doubleScale;
    } else {
      _currentScale = PhotoScale.normalScale;
    }
    setState(() {});
  }

  double _lastDx = 0, _lastDy = 0;

  void _onHorizontalDragStart(DragStartDetails details) {
    _lastDx = details.globalPosition.dx;
    _lastDy = details.globalPosition.dy;
  }

  void _onHorizontalDragUpdate(
      DragUpdateDetails details, BuildContext context) {
    double dx = details.globalPosition.dx - _lastDx;
    double dy = details.globalPosition.dy - _lastDy;
    if (dx.abs() > 0.5 || dy.abs() > 0.5) {
      _marginLeft += dx;
      _marginTop += dy;
      print("_marginTop == $_marginTop, _marginLeft == $_marginLeft");
      setState(() {});
    }
    _lastDx = details.globalPosition.dx;
    _lastDy = details.globalPosition.dy;
  }

  void _onHorizontalDragEnd(DragEndDetails details) {}

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }
}
